#include "SetAssociativeCache.h"

SetAssociativeCache::SetAssociativeCache(unsigned size, unsigned lineSize, unsigned linesPerSet) :
	Cache(size, lineSize), linesPerSet(linesPerSet)
{
	lines = size / lineSize;

	indexBits = lines / linesPerSet;
	indexBits = log2(indexBits);
	offsetBits = log2(lineSize);

	tagBits = adressSize - indexBits - offsetBits;

	int index = std::pow((double)2, (double)indexBits);
	cache = new int*[index];
	for(int i = 0; i < index; ++i)
	{
		cache[i] = new int[linesPerSet];
		for(int l = 0; l < linesPerSet; ++l)
			cache[i][l] = -1;
	}
}

SetAssociativeCache::~SetAssociativeCache(void)
{
	int index = std::pow((double)2, (double)indexBits);
	for(int i = 0; i < index; ++i)
		delete [] cache[i];

	delete [] cache;
}

float SetAssociativeCache::getFilled()
{
	int fullCounter = 0;
	int index = std::pow((double)2, (double)indexBits);
	for(int i = 0; i < index; ++i)
		for(int l = 0; l < linesPerSet; ++l)
			if(cache[i][l] != -1)
				fullCounter++;

	std::cout << "FullCounter: " << fullCounter << std::endl;
	std::cout << "lines: " << lines << std::endl;
	return (float)fullCounter / lines;
}

bool SetAssociativeCache::checkHit()
{
	std::cout << "index = " << currentIndex << std::endl;

	for(int i=0; i<linesPerSet; i++)
	{
		if(cache[currentIndex][i] == currentTag)
		{
			std::cout << "cache[index][set] = " << cache[currentIndex][i] << " | txt.Tag = " << currentTag << std::endl;
			std::cout << "Hit\n";
			return true;
		}
	}

	for(int i=0; i<linesPerSet; i++)
	{ 
		if(cache[currentIndex][i] == -1)
		{
			cache[currentIndex][i] = currentTag;
			std::cout << "Miss\n";
			return false;
		}
	}
	std::cout << "Miss\n";
	cache[currentIndex][0] = currentTag;
	return false;
}

